package app.pages;

import java.util.ArrayList;
import java.util.List;

import app.model.Member;
import app.model.Role;

import com.vaadin.data.validator.EmailValidator;
import com.vaadin.data.validator.StringLengthValidator;
import com.vaadin.ui.Button;
import com.vaadin.ui.Button.ClickEvent;
import com.vaadin.ui.Button.ClickListener;
import com.vaadin.ui.HorizontalLayout;
import com.vaadin.ui.TextField;
import com.vaadin.ui.Window;

public class RegisterWindow extends Window{

	private Role role;

	// Fields needed for register
	private TextField companyNameField;
	private TextField emailField;
	private TextField usernameField;
	private TextField passwordField;
	private TextField passwordConField;
	EmailValidator emailValidator;

	RegisterWindow(Role role){

		// Setting the pointer for Role
		this.role = role;

		// Style window
		setWidth("400px");
		setHeight("200px");
		setModal(true);

		// Fields needed for register
		companyNameField  = new TextField("Company name");
		emailField        = new TextField("Email");
		usernameField 	  = new TextField("Username");
		passwordField     = new TextField("Password");
		passwordConField  = new TextField("Confirm password");

		// Setting fields to required
		companyNameField.setRequired(true);
		emailField.setRequired(true);
		usernameField.setRequired(true);
		passwordField.setRequired(true);
		passwordConField.setRequired(true);
		
		// Setting the TextFields number of columns
		companyNameField.setColumns(20);
		emailField.setColumns(20);
		usernameField.setColumns(20);
		passwordField.setColumns(20);
		passwordConField.setColumns(20);

		// Adding validator to emailField
		emailValidator = new EmailValidator("The email you've entered is incorrect, please try again");
		emailField.addValidator(emailValidator);

		// Adding components
		addComponent(companyNameField);
		addComponent(emailField);
		addComponent(usernameField);
		addComponent(passwordField);
		addComponent(passwordConField);

		// Call to the buttons creation methods
		createRegisterAndCancelButtons();
	}

	/** This method will create register and cancel buttons and validate the fields*/
	public void createRegisterAndCancelButtons(){

		HorizontalLayout buttonsLayout = new HorizontalLayout();

		// Creating buttons
		Button registerButton = new Button("register",new ClickListener(){

			@Override public void buttonClick(ClickEvent event) {

				if(validateFields()){

					Member simpleUserOrDevMember = new Member(companyNameField.getValue().toString(),
							emailField.getValue().toString(), role, usernameField.getValue().toString(),
							passwordField.getValue().toString());

					showNotification("Your account has been created");
					System.out.println("Your account has been created");
				}
			}
		});

		Button cancelButton = new Button("cancel",new ClickListener(){

			@Override public void buttonClick(ClickEvent event) {
				close();
			}
		});

		// Adding buttons to the layout
		buttonsLayout.addComponent(registerButton);
		buttonsLayout.addComponent(cancelButton);
		addComponent(buttonsLayout);
	}

	/** This method will validate all the fields of the custom form */ 
	public boolean validateFields(){

		String tempStringPwd = null;
		String tempStringPwdC = null;
		boolean isValid = true;

		for(ReturnMessage retMess : fieldsEmptyOrNot()){

			if(retMess.isOK == false){

				if(retMess.field.getCaption().equals("Email") && !emailValidator.isValid(emailField.getValue())){
					showNotification("The field email is invalid, please try again");
					isValid = false;
					System.out.println("The field email is invalid, please try again");
				}

				if(retMess.field.getCaption().equals("Password")){ 
					tempStringPwd = retMess.field.getValue().toString();
					isValid = false;
				}

				if(retMess.field.getCaption().equals("Confirm Password")){
					tempStringPwdC = retMess.field.getValue().toString();
					isValid = false;
				}

				if(!(tempStringPwd == tempStringPwdC)){
					showNotification("The password didn't match, please try again");
					isValid = false;
					System.out.println("The password didn't match, please try again");
				}

			} else{

				showNotification("the field " + retMess.field.getCaption() + " is empty, please fill it to complete registration");
				isValid = false;
				System.out.println("the field " + retMess.field.getCaption() + " is empty, please fill it to complete registration");
			}
		}

		return isValid;
	}

	/** This method will check if field are empty and return a list of fields 
	 *  It won't be called directly, it will be used by validateFields() method
	 * */ 
	public List<ReturnMessage> fieldsEmptyOrNot(){

		boolean isEmpty = false;
		List<ReturnMessage> returnMessageList = new ArrayList<ReturnMessage>();

		// If fields are empty, sets isEmpty to true, else to false
		if(companyNameField.getValue().toString().isEmpty()){ isEmpty = true; 
		} else { isEmpty = false; }

		if(emailField.getValue().toString().isEmpty()){ isEmpty = true; 
		} else { isEmpty = false; }
		
		if(usernameField.getValue().toString().isEmpty()){ isEmpty = true; 
		} else { isEmpty = false; }

		if(passwordField.getValue().toString().isEmpty()){ isEmpty = true; 
		} else { isEmpty = false; }

		if(passwordConField.getValue().toString().isEmpty()){ isEmpty = true; 
		} else { isEmpty = false; }

		// Adding messages to the list
		returnMessageList.add( new ReturnMessage(companyNameField,isEmpty));
		returnMessageList.add( new ReturnMessage(emailField,isEmpty));
		returnMessageList.add( new ReturnMessage(usernameField,isEmpty));
		returnMessageList.add( new ReturnMessage(passwordField,isEmpty));
		returnMessageList.add( new ReturnMessage(passwordConField,isEmpty));

		return returnMessageList;
	}

	/** Used to create a type which can return a boolean and a message */ 
	public static class ReturnMessage{

		private TextField field;
		private boolean isOK;

		public ReturnMessage(TextField field, boolean isOK){
			this.field = field;
			this.isOK = isOK;
		}
	}
}